#include "mainwindow.h"

#include <QContextMenuEvent>
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMenu>
#include <QMessageBox>
#include <QNetworkReply>
#include <QPainter>
#include <QTimer>

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);

    // 设置窗口属性
    setWindowFlag(Qt::FramelessWindowHint);  // 无边框
    setFixedSize(width(), height());         // 固定窗口大小

    // 由于在资源文件中, 添加中文名称的图标, 会报错, 而请求回来的天气类型又都是中文, 比如“晴”、“小雨” 等
    // 因此定义了一个Map, 用于英文到中文的转换:
    mTypeMap.insert("暴雪", ":/res/type/BaoXue.png");
    mTypeMap.insert("暴雨", ":/res/type/BaoYu.png");
    mTypeMap.insert("暴雨到大暴雨", ":/res/type/BaoYuDaoDaBaoYu.png");
    mTypeMap.insert("大暴雨", ":/res/type/DaBaoYu.png");
    mTypeMap.insert("大暴雨到特大暴雨", ":/res/type/DaBaoYuDaoTeDaBaoYu.png");
    mTypeMap.insert("大到暴雪", ":/res/type/DaDaoBaoXue.png");
    mTypeMap.insert("大雪", ":/res/type/DaXue.png");
    mTypeMap.insert("大雨", ":/res/type/DaYu.png");
    mTypeMap.insert("冻雨", ":/res/type/DongYu.png");
    mTypeMap.insert("多云", ":/res/type/DuoYun.png");
    mTypeMap.insert("浮沉", ":/res/type/FuChen.png");
    mTypeMap.insert("雷阵雨", ":/res/type/LeiZhenYu.png");
    mTypeMap.insert("雷阵雨伴有冰雹", ":/res/type/LeiZhenYuBanYouBingBao.png");
    mTypeMap.insert("霾", ":/res/type/Mai.png");
    mTypeMap.insert("强沙尘暴", ":/res/type/QiangShaChenBao.png");
    mTypeMap.insert("晴", ":/res/type/Qing.png");
    mTypeMap.insert("沙尘暴", ":/res/type/ShaChenBao.png");
    mTypeMap.insert("特大暴雨", ":/res/type/TeDaBaoYu.png");
    mTypeMap.insert("undefined", ":/res/type/undefined.png");
    mTypeMap.insert("雾", ":/res/type/Wu.png");
    mTypeMap.insert("小到中雪", ":/res/type/XiaoDaoZhongXue.png");
    mTypeMap.insert("小到中雨", ":/res/type/XiaoDaoZhongYu.png");
    mTypeMap.insert("小雪", ":/res/type/XiaoXue.png");
    mTypeMap.insert("小雨", ":/res/type/XiaoYu.png");
    mTypeMap.insert("雪", ":/res/type/Xue.png");
    mTypeMap.insert("扬沙", ":/res/type/YangSha.png");
    mTypeMap.insert("阴", ":/res/type/Yin.png");
    mTypeMap.insert("雨", ":/res/type/Yu.png");
    mTypeMap.insert("雨夹雪", ":/res/type/YuJiaXue.png");
    mTypeMap.insert("阵雪", ":/res/type/ZhenXue.png");
    mTypeMap.insert("阵雨", ":/res/type/ZhenYu.png");
    mTypeMap.insert("中到大雪", ":/res/type/ZhongDaoDaXue.png");
    mTypeMap.insert("中到大雨", ":/res/type/ZhongDaoDaYu.png");
    mTypeMap.insert("中雪", ":/res/type/ZhongXue.png");
    mTypeMap.insert("中雨", ":/res/type/ZhongYu.png");


    mNetAccessManager = new QNetworkAccessManager(this);
    connect(mNetAccessManager, &QNetworkAccessManager::finished, this, [=](QNetworkReply* reply){
        int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        if ( reply->error() != QNetworkReply::NoError || status_code != 200 ) {
            qDebug("%s(%d) error: %s", __FUNCTION__, __LINE__, reply->errorString().toLatin1().data());
            QMessageBox::warning(this, "天气", "请求数据失败！", QMessageBox::Ok);
        } else {
            QByteArray byteArray = reply->readAll();
            parseJson(byteArray);
            updateUI();
        }
        reply->deleteLater();
    });
}

void MainWindow::mousePressEvent(QMouseEvent *ev)
{
    if (ev->button() == Qt::LeftButton) {
        m_distance = ev->globalPos() - this->geometry().topLeft();
    } else if (ev->button() == Qt::RightButton) {
        QMenu menu;
        QAction* exitAct = menu.addAction(QIcon(":/res/close.png"), "退出");
        connect(exitAct, &QAction::triggered, this, &QMainWindow::close);
        menu.exec(QCursor::pos());
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *ev)
{
    if (ev->buttons() & Qt::LeftButton) {
        this->move(ev->globalPos() - m_distance);
    }
}

void MainWindow::on_btnSearch_clicked()
{
    QUrl url("http://t.weather.itboy.net/api/weather/city/101010100");
    mNetAccessManager->get(QNetworkRequest(url));
}

void MainWindow::updateUI()
{
    // 更新日期
    ui->lblDate0->setText(mYesterday.ymd.split("-")[1] + "/" + mYesterday.ymd.split("-")[2]);
    QList<QLabel*> mDateList {ui->lblDate1, ui->lblDate2, ui->lblDate3, ui->lblDate4, ui->lblDate5};
    for (int i = 0; i < mDateList.size(); i++) {
       mDateList[0]->setText(mForecast[i].ymd.split("-")[1] + "/" + mForecast[i].ymd.split("-")[2]);
    }

    // 更新星期
    ui->lblWeek0->setText("昨天");
    ui->lblWeek1->setText("今天");
    ui->lblWeek2->setText("明天");
    QList<QLabel*> mWeekList {ui->lblWeek3, ui->lblWeek4, ui->lblWeek5};
    for (int i = 0; i < mWeekList.size(); i++) {
        mWeekList[i]->setText(mForecast[i+2].week);
    }

    // 更新天气类型和图标
    ui->lblType0->setText(mYesterday.type);
    ui->lblTypeIcon0->setPixmap(mTypeMap[mYesterday.type]);
    ui->lblTypeIcon->setPixmap(mTypeMap[mForecast[0].type]);
    QList<QLabel*> mTypeList {ui->lblType1, ui->lblType2, ui->lblType3, ui->lblType4, ui->lblType5};
    QList<QLabel*> mTypeIconList {ui->lblTypeIcon1, ui->lblTypeIcon2, ui->lblTypeIcon3, ui->lblTypeIcon4, ui->lblTypeIcon5};
    for (int i = 0; i < mTypeList.size(); i++) {
        mTypeList[i]->setText(mForecast[i].type);
        mTypeIconList[i]->setPixmap(mTypeMap[mForecast[i].type]);
    }

    // 更新风力、风向
    ui->lblFl0->setText(mYesterday.fl);
    ui->lblFx0->setText(mYesterday.fx);
    QList<QLabel*> mFxList {ui->lblFl1, ui->lblFl2, ui->lblFl3, ui->lblFl4, ui->lblFl5};
    QList<QLabel*> mFlList {ui->lblFx1, ui->lblFx2, ui->lblFx3, ui->lblFx4, ui->lblFx5};
    for (int i = 0; i < mFxList.size(); i++) {
        mFxList[i]->setText(mForecast[i].fx);
        mFlList[i]->setText(mForecast[i].fl);
    }

    // 更新空气质量
    if (mYesterday.aqi > 0 && mYesterday.aqi <= 50) {
        ui->lblQuality0->setText("优");
        ui->lblQuality0->setStyleSheet("background-color: rgb(121, 184, 0);");
    } else if (mYesterday.aqi > 50 && mYesterday.aqi <= 100) {
        ui->lblQuality0->setText("良");
        ui->lblQuality0->setStyleSheet("background-color: rgb(255, 187, 23);");
    } else if (mYesterday.aqi > 100 && mYesterday.aqi <= 150) {
        ui->lblQuality0->setText("轻度");
        ui->lblQuality0->setStyleSheet("background-color: rgb(255, 87, 97);");
    } else if (mYesterday.aqi > 150 && mYesterday.aqi <= 200) {
        ui->lblQuality0->setText("中度");
        ui->lblQuality0->setStyleSheet("background-color: rgb(235, 17, 27);");
    } else if (mYesterday.aqi > 200 && mYesterday.aqi <= 300) {
        ui->lblQuality0->setText("重度");
        ui->lblQuality0->setStyleSheet("background-color: rgb(170, 0, 0);");
    } else {
        ui->lblQuality0->setText("严重");
        ui->lblQuality0->setStyleSheet("background-color: rgb(110, 0, 0);");
    }

    QList<QLabel*> mAqiList;
    mAqiList << ui->lblQuality1 << ui->lblQuality2 << ui->lblQuality3 << ui->lblQuality4 << ui->lblQuality5;
    for (int i = 0; i < 5; i++) {
        if (mForecast[i].aqi > 0 && mForecast[i].aqi <= 50) {
            mAqiList[i]->setText("优");
            mAqiList[i]->setStyleSheet("background-color: rgb(121, 184, 0);");
        } else if (mForecast[i].aqi > 50 && mForecast[i].aqi <= 100) {
            mAqiList[i]->setText("良");
            mAqiList[i]->setStyleSheet("background-color: rgb(255, 187, 23);");
        } else if (mForecast[i].aqi > 100 && mForecast[i].aqi <= 150) {
            mAqiList[i]->setText("轻度");
            mAqiList[i]->setStyleSheet("background-color: rgb(255, 87, 97);");
        } else if (mForecast[i].aqi > 150 && mForecast[i].aqi <= 200) {
            mAqiList[i]->setText("中度");
            mAqiList[i]->setStyleSheet("background-color: rgb(235, 17, 27);");
        } else if (mForecast[i].aqi > 200 && mForecast[i].aqi <= 300) {
            mAqiList[i]->setText("重度");
            mAqiList[i]->setStyleSheet("background-color: rgb(170, 0, 0);");
        } else {
            mAqiList[i]->setText("严重");
            mAqiList[i]->setStyleSheet("background-color: rgb(110, 0, 0);");
        }
    }

}

void MainWindow::parseJson(QByteArray &replyJson)
{
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(replyJson, &err);
    if ( err.error != QJsonParseError::NoError ) {
        qDebug("%s(%d) error: %s", __FUNCTION__, __LINE__, err.errorString().toLatin1().data());
        return;
    }

    QJsonObject rootObj = doc.object();
    QString message = rootObj.value("message").toString();
    if ( !message.contains("success") ) {
        QMessageBox::warning(this, "天气", "请求数据失败！", QMessageBox::Ok);
        return;
    }

    ui->lblCity->setText(rootObj.value("cityInfo").toObject().value("city").toString());

    // 1. 解析yesterday数据
    QJsonObject yesterdayOBJ = rootObj.value("data").toObject().value("yesterday").toObject();
    mYesterday.date = yesterdayOBJ.value("date").toString();
    mYesterday.high = yesterdayOBJ.value("high").toString();
    mYesterday.low = yesterdayOBJ.value("low").toString();
    mYesterday.ymd = yesterdayOBJ.value("ymd").toString();
    mYesterday.week = yesterdayOBJ.value("week").toString();
    mYesterday.sunrise = yesterdayOBJ.value("sunrise").toString();
    mYesterday.sunset = yesterdayOBJ.value("sunset").toString();
    mForecast[0].aqi = yesterdayOBJ.value("aqi").toDouble();
    mYesterday.fx = yesterdayOBJ.value("fx").toString();
    mYesterday.fl = yesterdayOBJ.value("fl").toString();
    mYesterday.type = yesterdayOBJ.value("type").toString();
    mYesterday.notice = yesterdayOBJ.value("notice").toString();

    // 2. 解析forecast数据
    QJsonArray forecastOBJArr = rootObj.value("data").toObject().value("forecast").toArray();
    for (int i = 0; i < 5; i++) {
        QJsonObject forecastOBJ = forecastOBJArr[i].toObject();
        mForecast[i].date = forecastOBJ.value("date").toString();
        mForecast[i].high = forecastOBJ.value("high").toString();
        mForecast[i].low = forecastOBJ.value("low").toString();
        mForecast[i].ymd = forecastOBJ.value("ymd").toString();
        mForecast[i].week = forecastOBJ.value("week").toString();
        mForecast[i].sunrise = forecastOBJ.value("sunrise").toString();
        mForecast[i].sunset = forecastOBJ.value("sunset").toString();
        mForecast[i].aqi = forecastOBJ.value("aqi").toDouble();
        mForecast[i].fx = forecastOBJ.value("fx").toString();
        mForecast[i].fl = forecastOBJ.value("fl").toString();
        mForecast[i].type = forecastOBJ.value("type").toString();
        mForecast[i].notice = forecastOBJ.value("notice").toString();
    }
}

MainWindow::~MainWindow() { delete ui; }

